package com.api.shop.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * JWT: JSON Web Token
 */
public class JWTUtil {

    public static final String SALT = "API_SHOP_TOKEN_KEY";

    public static String createToken(String id){
        String issuer = "SYSTEM";
        String subject = "ALL_USER";
        long ttlMillis = 60 * 60 * 24 * 7;
        return createToken(id, issuer, subject, ttlMillis);
    }

    /**
     *  生成 token
     * @param id 编号
     * @param issuer 该 JWT 的签发者，是否使用是可选的
     * @param subject 该 JWT 所面向的用户，是否使用是可选的
     * @param ttlMillis 签发时间（有效时间，过期会报错）
     * @return token String
     */
    public static String createToken(String id, String issuer, String subject, long ttlMillis){
        // 签名算法，对 token 进行签名
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成签发时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // 通过秘钥签名 JWT
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SALT);

        Key signKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject)
                .setIssuer(issuer).signWith(signatureAlgorithm, signKey);

        if(ttlMillis >= 0){
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        return builder.compact();
    }

    public static void parseJwt(String jwt){
        Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(SALT))
                .parseClaimsJws(jwt).getBody();
        System.out.println("ID: " + claims.getId());
        System.out.println("Subject: " + claims.getSubject());
        System.out.println("Issuer: " + claims.getIssuer());
        System.out.println("Expiration: " + claims.getExpiration());
    }

}
